<template>
    <view class="page">
        <view :style="{ height: headerHeightStyle }" class="header" v-if="headerHeight !== 0">
            <view
                :class="headerBgColorClass"
                :style="{ height: headerHeightStyle, backgroundColor: headerBgColorStyle }"
                class="fixed-top"
            >
                <view :style="{ top: `${statusBarHeight}px` }" style="position: relative;">
                    <slot name="header">
                        <uxt-nav-bar :back="back" bg-color=" ">
                            {{ title }}
                            <template slot="right">
                                <uxt-icon
                                    @click="showSideModal = true"
                                    type="ellipsis-v"
                                    v-if="hasSide"
                                ></uxt-icon>
                            </template>
                        </uxt-nav-bar>
                    </slot>
                </view>
            </view>
        </view>
        <slot></slot>
        <view :style="{ height: footerHeightStyle }" class="footer" v-if="footerHeight">
            <view :style="{ height: footerHeightStyle }" class="fixed-bottom">
                <slot name="footer"></slot>
            </view>
        </view>
        <uxt-modal
            :position="sidePosition"
            @closed="handleSideClosed"
            @opened="handleSideOpened"
            v-if="hasSide"
            v-model="showSideModal"
        >
            <slot name="side"></slot>
        </uxt-modal>
        <uxt-page-loading :show="pageLoading.show" :color="pageLoading.color"></uxt-page-loading>
        <uxt-loading
            :show="loading.show"
            :color="loading.color"
            :bg-color="loading.bgColor"
            :tip="loading.tip"
        ></uxt-loading>
        <uxt-notify
            :bg-color="notify.bgColor"
            :color="notify.color"
            :duration="0"
            :icon="notify.icon"
            :message="notify.message"
            :type="notify.type"
            @click="handleNotifyClick"
            v-model="notify.show"
        ></uxt-notify>
        <uxt-toast
            :duration="0"
            :icon="toast.icon"
            :message="toast.message"
            :no-click="toast.noClick"
            :type="toast.type"
            v-model="toast.show"
        ></uxt-toast>
        <uxt-dialog
            :icon="dialog.icon"
            :message="dialog.message"
            :title="dialog.title"
            :type="dialog.type"
            :title-bg-color="dialog.titleBgColor"
            @cancel="handleDialogCancel"
            @ok="handleDialogOk"
            v-model="dialog.show"
        ></uxt-dialog>
    </view>
</template>

<script>
import uxtNavBar from './uxt-nav-bar.vue'
import uxtIcon from './uxt-icon.vue'
import uxtModal from './uxt-modal.vue'
import uxtPageLoading from '@xtcoder/uxt/components/uxt-page-loading.vue'
import uxtLoading from '@xtcoder/uxt/components/uxt-loading.vue'
import uxtNotify from './uxt-notify.vue'
import uxtToast from './uxt-toast.vue'
import uxtDialog from './uxt-dialog.vue'

export default {
    name: 'uxt-page',
    components: {
        uxtNavBar,
        uxtIcon,
        uxtModal,
        uxtPageLoading,
        uxtLoading,
        uxtNotify,
        uxtToast,
        uxtDialog
    },
    props: {
        // 顶部高度, 默认为导航栏高度，不写slot默认显示导航栏，传0不显示顶部
        headerHeight: {
            type: [Number, String]
        },
        // 头部背景
        headerBgColor: {
            type: String,
            default: 'theme'
        },
        // 标题
        title: {
            type: String
        },
        back: {
            type: Boolean,
            default: true
        },
        // 底部高度
        footerHeight: {
            type: [Number, String]
        },
        // 显示侧边栏
        showSide: {
            type: Boolean,
            default: false
        },
        // 侧边栏位置
        sidePosition: {
            type: String,
            default: 'left',
            validator(value) {
                return ['left', 'right'].includes(value)
            }
        }
    },
    data() {
        let dfPageLoading = {
            show: false,
            color: 'red'
        }
        let dfLoading = {
            show: false,
            color: 'theme',
            bgColor: 'white',
            tip: '加载中...'
        }
        let dfNotify = {
            id: 0,
            show: false,
            message: '消息',
            type: '',
            duration: 3000,
            icon: '',
            color: '',
            bgColor: 'theme',
            click() {}
        }
        let dfToast = {
            id: 0,
            show: false,
            message: '消息',
            type: 'df',
            duration: 3000,
            icon: '',
            noClick: false
        }
        let dfDialog = {
            show: false,
            title: '提示',
            message: '提示内容',
            type: 'alert',
            icon: '',
            titleBgColor: 'theme'
        }
        return {
            statusBarHeight: this.systemInfo.statusBarHeight,
            showSideModal: this.showSide,
            dfPageLoading,
            pageLoading: Object.assign(dfPageLoading),
            dfLoading,
            loading: Object.assign(dfLoading),
            dfNotify,
            notify: Object.assign(dfNotify),
            dfToast,
            toast: Object.assign(dfToast),
            dfDialog,
            dialog: Object.assign(dfDialog)
        }
    },
    computed: {
        headerBgColorClass() {
            return this.getColor(this.headerBgColor, 'bg-').classes
        },
        headerBgColorStyle() {
            return this.getColor(this.headerBgColor, 'bg-').styles
        },
        headerHeightStyle() {
            if (this.headerHeight === 0) {
                return ''
            } else if (this.headerHeight) {
                return `calc(${this.getSize(this.headerHeight).styles} + ${
                    this.systemInfo.statusBarHeight
                }px)`
            } else {
                return `${this.systemInfo.navBarHeight + this.systemInfo.statusBarHeight}px`
            }
        },
        footerHeightStyle() {
            return this.getSize(this.footerHeight).styles
        },
        hasSide() {
            if (this.$slots.side) {
                return true
            }
            return false
        }
    },
    watch: {
        showSide(newVal, oldVal) {
            this.showSideModal = newVal
        }
    },
    methods: {
        handleSideOpened() {
            this.$emit('sideopened')
        },
        handleSideClosed() {
            this.$emit('sideclosed')
        },
        /*****uxtPageLoading*****/
        setPageLoading(p) {
            if (typeof p !== 'object') {
                return
            }
            this.pageLoading = Object.assign({}, this.dfPageLoading, p, { show: false })
        },
        showPageLoading() {
            this.pageLoading.show = true
        },
        hidePageLoading() {
            this.pageLoading.show = false
        },
        /*****uxtLoading*****/
        setLoading(p) {
            if (typeof p !== 'object') {
                return
            }
            this.loading = Object.assign({}, this.dfLoading, p, { show: false })
        },
        showLoading() {
            this.loading.show = true
        },
        hideLoading() {
            this.loading.show = false
        },
        /*****uxtNotify*****/
        setNotify(p) {
            if (typeof p !== 'object') {
                return
            }
            this.notify = Object.assign({}, this.dfNotify, p, { show: false, id: this.notify.id })
        },
        showNotify(type) {
            type && (this.notify.type = type)
            this.notify.show = true
            this.notify.id && clearTimeout(this.notify.id)
            if (this.notify.duration > 0) {
                this.notify.id = setTimeout(() => {
                    this.notify.show = false
                }, this.notify.duration)
            }
        },
        hideNotify() {
            this.notify.show = false
        },
        handleNotifyClick() {
            if (typeof this.notify.click === 'function') {
                this.notify.click()
            }
        },
        /*****uxtToast*****/
        setToast(p) {
            if (typeof p !== 'object') {
                return
            }
            this.toast = Object.assign({}, this.dfToast, p, { show: false, id: this.toast.id })
        },
        showToast(type) {
            type && (this.toast.type = type)
            this.toast.show = true
            this.toast.id && clearTimeout(this.toast.id)
            if (this.toast.duration > 0 && this.toast.type !== 'loading') {
                this.toast.id = setTimeout(() => {
                    this.toast.show = false
                }, this.toast.duration)
            }
        },
        hideToast() {
            this.toast.show = false
        },
        /*****uxtDialog*****/
        setDialog(p) {
            if (typeof p !== 'object') {
                return
            }
            this.dialog = Object.assign({}, this.dfDialog, p, { show: false })
        },
        showDialog(type, resolve) {
            this.dialog.type = type
            this.dialog.resolve = resolve
            this.dialog.show = true
        },
        handleDialogOk() {
            this.dialog.resolve(true)
        },
        handleDialogCancel() {
            this.dialog.resolve(false)
        }
    }
}
</script>

<style lang="scss" scoped>
.page {
    min-height: 100%;
}
.header {
    .fixed-top,
    .fixed-bottom {
        z-index: 888;
    }
}
</style>
